﻿#include "Lisp.h"

#include "Readline.h"
#include "Reader.h"
#include "Printer.h"
#include "Env.h"

Lisp::ValPtr READ(const std::string &input);
Lisp::ValPtr EVAL(Lisp::ValPtr ast, Lisp::EnvPtr env);
std::string PRINT(Lisp::ValPtr val);
std::string Rep(const std::string &input);

static Lisp::Readline s_readline;

int main()
{
  std::string prompt = "user> ";
  std::string input;
  while (s_readline.Get(prompt, input))
  {
    if (input.empty())
      continue;
      
    try {
      std::cout << Rep(input) << std::endl;
    } catch (const std::exception &e) {
      std::cout << "Err: " << e.what() << std::endl;
    }
  }
  return 0;
}

Lisp::ValPtr READ(const std::string &input)
{
  return Lisp::ReadStr(input);
}

Lisp::ValPtr EVAL(Lisp::ValPtr val)
{
  return val;
}

Lisp::ValPtr EVAL(Lisp::ValPtr ast, Lisp::EnvPtr env)
{
  return ast->Eval(env);
}

Lisp::ValPtr APPLY(Lisp::ValPtr op, Lisp::ListPtr args)
{
  return op;
}

std::string PRINT(Lisp::ValPtr val)
{
  return Lisp::PrintStr(val);
}

std::string Rep(const std::string &input)
{
  return PRINT(EVAL(READ(input)));
}